<template>
    <div :class="classes" ref="select">
        <div ref="control" :class="{ [prefixCls + '-select-control']: true, 'focus': show }">
            <div :class="[prefixCls + '-select-tags']" v-if="multiple">
                <span v-for="(item, index) in values" :key="index">
                    <span :class="[prefixCls + '-select-tag']" v-if="maxTagCount ? index < maxTagCount : 'false'">
                        <span class="select-text">{{ item.label }}</span>
                        <i class="icon icon-del" @click="delItem(item)" ref="tag"></i>
                    </span>
                </span>
                <span class="select-count" v-if="values.length > maxTagCount">+{{ values.length - maxTagCount }}...</span>
                <span
                   class="multiple-placeholder"
                   v-if="values.length == 0 && multiple && !isMultipleKeyWord"
                   :class="{ 'placeholder': showPlaceholder }">
                    {{placeholder}}
                </span>
                <input 
                    ref="multipleSearch"
                    type="text" 
                    class="select-multiple-search-input"
                    v-model="keyWord"
                    v-if="showSearch"
                    @input="_multipleInput"
                    @blur="_multipleBlur"
                    :style="{width: 100 / (values.length + 2) + '%'}"
                />
            </div>
            <div class="input-control" v-if="!showSearch && !multiple" :class="{ 'placeholder': showPlaceholder }" v-text="text"></div>
            <input type="text" class="select-search-input" :placeholder="cloneSearchPlaceholder" v-model="keyWord" v-if="showSearch && !multiple" @keyup="_keyup" @input="_input">
            <i class="icon icon-arrow-down"></i>
        </div>
        <transition name="select-zoom-in-top">
            <div :class="dropdownCls" v-if="show" ref="drop">
                <div :class="[prefixCls + '-select-drop-down-scroll']">
                    <div :class="[prefixCls + '-select-drop-down-border']" :style="showLiNum" ref="downScroll">
                        <div v-if="filterOptionArray.length == 0" class="no-data">无数据</div>
                        <!-- <div v-if="newArray.length == 0 && showSearch && !keyWord" class="no-data">无匹配数据</div>
                        <div v-else-if="filterOptionArray.length == 0" class="no-data">无数据</div> -->
                        <ul>
                            <li 
                                v-for="(item, index) in filterOptionArray" 
                                :key="index" 
                                :data-value="item.value"
                                @click="_itemClick(item, $event)"
                                :class="{ 'disabled': item.disabled, 'active': selectValue(item) }" ref="li">{{ item.label }}
                                <slot></slot>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </transition>
    </div>
</template>
<script>
import { prefixCls } from '../prefix'
import './select.css'
import axios from 'axios';
import popup from '../../utils/popup';

export default {
    name: `${prefixCls}Select`,
    data() {
        return {
            prefixCls: prefixCls,
            show: false,
            optionArray: this.option, //下拉数据列表
            showPlaceholder: this.placeholder ? true : false,
            text: this.placeholder, //默认显示的项
            keyWord: '',
            liHeight: '', //li高度
            activeVal: this.value, //当前选中项，多选
            isClickTag: false, //是否点击了tag的删除 
            newArray: [], //搜索出来的内容,
            isOpenSeach: true, // 是否打开检索关键词功能
            values: [], //选中数据
            select_index: 0,
            isMultipleKeyWord: false,
            showSearchPlaceholder: '请选择',
            cloneSearchPlaceholder: this.searchPlaceholder,
            showManual: false,
        }
    },
    props: {
        value: {//通过v-model传进来
            type: [String, Array, Number],
            default: ()=> { 
                return []
            }
        }, 
        placeholder: { //默认显示的文本
            type: String,
            default: '请选择'
        },
        showNum: { //显示下拉个数，超出显示滚动条
            type: Number,
            default: 6
        },
        option: Array, //下拉选顶
        optionUrl: String, //请求数据地址，同时传了option，请求成功后会更新option
        disabled: { //是否禁用
            type: Boolean,
            default: false
        },
        showSearch: { //显示搜索输入框
            type: Boolean,
            default: false
        },
        searchPlaceholder: String, //仅对搜索有效，搜索输入框placeholder提示语
        transfer: { //弹层放置于body内
            type: Boolean,
            default: false
        },
        multiple: { //多选
            type: Boolean,
            default: false
        },
        size: String, //选择框尺寸
        maxTagCount: Number, //多选时最多显示多少个 tag
        transferClassName: String, //开启 transfer 时，给浮层添加额外的 class 名称
    },
    mounted() {
        this._setFirstText();
        /*//注册body点击事件
         document.body.addEventListener('click', this._bodyClick, false);*/
        //加载数据
        this._ajaxUrl();
        const element = this.$refs.select //组件下拉框
        document.addEventListener('click', this._showHide)
        //document.addEventListener('keydown', this.handleEscClose)
        Array.prototype.remove = function (val) {
            var index = this.indexOf(val);
            if (index > -1) {
                this.splice(index, 1);
            }
        };

        this.getOptionsValue(this.value)
    },
    watch: {
        value(val) {
            const placeholder = this.placeholder
            if (this.multiple) {
                if (Array.isArray(val) && !val.length) {
                    this.values = [];
                    //当value为空时重新赋值，保持数据响应
                    this.activeVal = val
                    this.text = placeholder ? placeholder : '请选择'
                    this.showPlaceholder = true
                }
            } else {
                // 单选
                if (val === '') {
                    this.activeVal = val
                    this.text = placeholder ? placeholder : '请选择'
                    if (this.showSearch) {
                        this.keyWord = ''
                    }
                    this.showPlaceholder = true
                }
            }
            this.getOptionsValue(val)
        },
        keyWord(val) {
            if (val) {
                if (this.showSearch) {
                    this.filterOptionArray = true
                }
            }
        },
        //监听数据项，重新赋值
        option(newVal, oldVal) {
            this.optionArray = newVal
            this.getOptionsValue(this.value)
        },
        //原生v-model绑定的值
        activeVal(val) {
            this.$emit("input", val);
        },
        show(val) {
            if(val && this.showSearch && !this.multiple) {
                if(!this.showManual) {
                    this.showSearchPlaceholder = this.cloneSearchPlaceholder;
                    this.cloneSearchPlaceholder = this.keyWord;
                    // this.keyWord = '';//带搜索时，不清空，会显示当前选择的内容
                }
            }

            if(!val && this.showSearch && !this.multiple) {
                if(!this.showManual) {
                    this.keyWord = this.cloneSearchPlaceholder;
                    this.cloneSearchPlaceholder = this.showSearchPlaceholder;
                }
                this.showManual = false;
            }
        }
    },
    methods: {
        _showHide(e) {
            if(this.show && e.target.className == 'disabled') {
                return false
            } 
            // 多选tag点击删除时候不收起下拉层
            if (this.multiple && this.isClickTag) {
                this.isClickTag = false;
                return false;
            }
            
            const target = e.target || e;
            if (this.$el.contains(target)) {
                this.disabled == false ? this.show = !this.show : "";

                if (this.transfer && this.show) {
                    this.$nextTick(() => {
                        popup.create({
                            drop: this.$refs.drop
                        })
                        const DOMRect1 = this.$refs.control.getBoundingClientRect(),
                            _w1 = DOMRect1.width;
                        this.$refs.drop.style.minWidth = _w1 + 'px';
                        this.$refs.drop.style.width = 'auto';
                    })
                }
                this.$nextTick(() => {
                    popup.position({
                        trigger: this.$refs.control, //触发层
                        drop: this.$refs.drop, //下拉层
                        body: this.transfer, //是否将弹层置于body中
                    })

                    //单选数据量大，定位到当前选中的数据项
                    if(this.select_index > 6 && !this.multiple) {
                        const down_scroll = this.$refs.downScroll
                        if(down_scroll) {
                            this.$refs.downScroll.scrollTop =  (this.select_index - 3) * 31
                        }
                    }

                    //多选模式、开始搜索、下拉数据出现搜索框focus
                    if(this.multiple && this.showSearch && this.show) {
                        this.$refs.multipleSearch.focus()
                    }
                })

                if (!this.keyWord) {
                    //搜索功能开启，没有关键词，不会显示li
                    if (this.show && this.optionArray.length > 0) {
                        this.$nextTick(() => {
                            this.liHeight = this.$refs.li[0].offsetHeight;
                        })
                    }
                } else {
                    const that = this
                    for (let i in this.optionArray) {
                        if (that.optionArray[i].label === this.keyWord) {
                            this.filterOptionArray = false
                        }
                    }
                }
                this.$emit('onOpenChange',this.show)
            } else {
                if (this.show) {
                    this.show = false;
                    this.$emit('onOpenChange',this.show)
                }
            }
        },
        //根据传入的value处理赋值问题
        getOptionsValue(value) {
            const isValue = [undefined, null, 'undefined'].includes(value)
            const select_option = this.option
            if (!isValue && Array.isArray(select_option) && select_option.length > 0) {
                if (!this.multiple) {
                    this.activeVal = value; //重新赋值
                    let hasEqual = false; //判断是否有匹配的值
                    for (let i in this.optionArray) {
                        const option_value = String(this.optionArray[i].value)
                        const _value = String(value)
                        if (option_value == _value) {
                            this.select_index = i
                            this.text = this.optionArray[i].label;
                            this.keyWord = this.optionArray[i].label;
                            this.showPlaceholder = false;
                            hasEqual = true;
                            break
                        }
                    }
                    if(!hasEqual) {
                        this.text = this.placeholder ? this.placeholder : '请选择';
                    }
                } else {
                    if(!Array.isArray(value)) return
                    this.activeVal = value //重新赋值
                    const values = value.map((item, index) => {
                        const label = this.findValueIndex(this.option, item)
                        if(label) {
                            return {
                                value: item,
                                label: label
                            }
                        }
                    });
                    const newValues = values.filter(d => {return d != undefined})
                    setTimeout(() => {
                        this.values = newValues;
                    });
                }

            }
        },
        _multipleInput(event) {
            this.isMultipleKeyWord = true
        },
        _multipleBlur(event) {
            if(!this.keyWord && this.isMultipleKeyWord) {
                this.isMultipleKeyWord = false
            }
        },
        findValueIndex(options, item) {
            const index = options.findIndex(d => d.value === item)
            if(index == -1) { return ''}
            return options[index].label
        },
        _itemClick(item, e) {
            if (!item.disabled) {
                if (this.multiple) {
                    // 多选
                    const _index = this.activeVal.findIndex(d => d === item.value)
                    _index !== -1 ? this.activeVal.remove(item.value) : this.activeVal.push(item.value)
                    
                    //处理展示数据values
                    const index = this.values.findIndex(d => d.value === item.value)
                    index !== -1 ? this.values.splice(index, 1) : this.values = this.values.concat(item)

                    this.text = this.activeVal.length === 0 ? this.placeholder : ''

                    this.keyWord = ''
                    if(this.showSearch) {
                        this.$refs.multipleSearch.focus()
                    }
                    this.$emit('on-change', this.activeVal);
                    this.$nextTick(() => {
                        popup.position({
                            trigger: this.$refs.control, //触发层
                            drop: this.$refs.drop, //下拉层
                            body: this.transfer, //是否将弹层置于body中
                        })
                    })
                } else {
                    // 单选
                    this.text = item.label
                    this.activeVal = item.value
                    this.show = false
                    this.$emit('on-change', item);
                    this.showPlaceholder = false

                    //搜索框
                    this.showSearch ? this.cloneSearchPlaceholder = item.label : "";
                }
                e.stopPropagation();
            }else{
                return false
            }
        },
        _setFirstText() {
            //设置第一项选项；如果有值则选中对应项，如果没值显示默认，没默认显示选第一项
            if (this.value) {
                for (let i in this.optionArray) {
                    if (this.optionArray[i].value == this.value) {
                        this.text = this.optionArray[i].label
                        //有值时去掉placeholder样式
                        this.showPlaceholder = false
                        break;
                    }
                }
            } else {
                if (!this.placeholder) {
                    this.text = this.optionArray[0].label
                    //有值时去掉placeholder样式
                    this.showPlaceholder = false
                }
            }
        },
        _searchBoxClick(e) {
            e.stopPropagation();
        },
        _ajaxUrl() {
            if (this.optionUrl) {
                axios.get(this.optionUrl).then((res) => {
                    this.optionArray = res.data.result;
                    this._setFirstText();
                }, res => {
                    console.log('error');
                });
            }
        },

        selectValue(item) {
            if(typeof this.activeVal == 'undefined') return
            if (this.multiple) {
                if (this.activeVal.indexOf(item.value) != -1) {
                    return item.value
                }
            } else {
                if(this.showSearch) {
                    // 开启搜索选项
                    //this.keyWord == item.label
                    return this.cloneSearchPlaceholder == item.label
                }else{
                    // 普通select
                    return String(this.activeVal) == String(item.value)
                }
            }
        },
        delItem(item) {
            // 多选中从input中删除已选项
            this.activeVal.remove(item.value)
            this.values.splice(this.values.findIndex(d => d.value === item.value), 1)

            if (this.activeVal.length === 0) {
                this.text = this.placeholder
            }
            this.isClickTag = true;
            this.$nextTick(()=> {
                popup.position({
                    trigger: this.$refs.control, //触发层
                    drop: this.$refs.drop, //下拉层
                    body: this.transfer, //是否将弹层置于body中
                })
            })
        },
        _keyup() {
            popup.position({
                trigger: this.$refs.control, //触发层
                drop: this.$refs.drop, //下拉层
                body: this.transfer, //是否将弹层置于body中
            })
        },
        _input() {
            // const target = this.$refs.control;
            // this.showManual = true;
            // if(!this.show && this.showSearch && target) {
            //     this._showHide(target);
            // }
        },
        //监听ESC关闭下拉层
        handleEscClose(event) {
            const code = event.keyCode;
            if(!this.show && this.showSearch && code !== 27) {
                this._showHide();
            }
            if(code === 27 && this.show){
                this.show = false;
                event.stopPropagation();
            }
        },
    },
    computed: {
        filterOptionArray: {
            get() {
                if (this.showSearch && this.isOpenSeach) {
                    //带搜索时
                    this.newArray = [];
                    this.optionArray.forEach((d, i) => {
                        if(d.label) {
                            if (d.label.indexOf(this.keyWord) > -1) {
                                this.newArray.push(d);
                            }
                        }
                    })
                    return this.newArray;
                } else {
                    return this.optionArray

                }
            },
            set(data) {
                this.isOpenSeach = data
            }
        },
        showLiNum() {
            this.$nextTick(() => {
                if (this.showNum && this.optionArray.length > this.showNum) {
                    return {
                        height: this.liHeight * this.showNum + 'px'
                    }
                }
            })
        },
        classes() {
            return [
                `${prefixCls}-select`,
                {
                    'open': this.show,
                    [prefixCls + '-select-multiple']: this.multiple,
                    [prefixCls + '-select-disabled']: this.disabled,
                    [prefixCls + '-select-' + this.size]: this.size
                }
            ]
        },
        dropdownCls() {
            return {
                [prefixCls + '-select-drop-down']: true,
                'is-multiple': this.multiple,
                [this.transferClassName]: this.transferClassName && this.transfer
            }
        }
    },
    beforeDestroy() {
        document.removeEventListener('click', this._showHide)
        //document.removeEventListener('keydown', this.handleEscClose)
        if (this.transfer) {
            popup.delete({
                drop: this.$refs.drop
            })
        }
    },
}
</script>
